

<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="" > <!--<![endif]-->
<head>
  <meta charset="utf-8">
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  
  <title>Simulation &mdash; NVIDIA PhysX SDK 4.1 Documentation</title>
  

  
  <link rel="shortcut icon" href="_static/images/favicon.ico"/>

  
  

  

  
  
    

  
  <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../_static/breathe.css" type="text/css" />
    <link rel="next" title="Advanced Collision Detection" href="AdvancedCollisionDetection.html" />
    <link rel="prev" title="Rigid Body Dynamics" href="RigidBodyDynamics.html" />
    <link href="../_static/css/nvidia_theme.css" rel="stylesheet" type="text/css">
    
    
        <style>
            .wy-nav-content::before {
                content: "PhysX 4.1 SDK Guide";
            }
        </style>
    


  
  <script src="../_static/js/modernizr.min.js"></script>

</head>

<body class="wy-body-for-nav">

   
  <div class="wy-grid-for-nav">

    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search">
          

          
            <a href="../Index.html" class="icon icon-home"> Python
          

          
          </a>

          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <ul class="current">
<li class="toctree-l1 current"><a class="reference internal" href="Index.html">User's Guide</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="License.html">PhysX License</a></li>
<li class="toctree-l2"><a class="reference internal" href="Introduction.html">Welcome to PhysX</a></li>
<li class="toctree-l2"><a class="reference internal" href="HelloWorld.html">Snippets</a></li>
<li class="toctree-l2"><a class="reference internal" href="BuildingWithPhysX.html">Building with PhysX</a></li>
<li class="toctree-l2"><a class="reference internal" href="API.html">The PhysX API</a></li>
<li class="toctree-l2"><a class="reference internal" href="Startup.html">Startup and Shutdown</a></li>
<li class="toctree-l2"><a class="reference internal" href="Threading.html">Threading</a></li>
<li class="toctree-l2"><a class="reference internal" href="Geometry.html">Geometry</a></li>
<li class="toctree-l2"><a class="reference internal" href="RigidBodyOverview.html">Rigid Body Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="RigidBodyCollision.html">Rigid Body Collision</a></li>
<li class="toctree-l2"><a class="reference internal" href="RigidBodyDynamics.html">Rigid Body Dynamics</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="">Simulation</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#callback-sequence">Callback Sequence</a></li>
<li class="toctree-l3"><a class="reference internal" href="#simulation-memory">Simulation memory</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#scene-limits">Scene Limits</a></li>
<li class="toctree-l4"><a class="reference internal" href="#k-data-blocks">16K Data Blocks</a></li>
<li class="toctree-l4"><a class="reference internal" href="#scratch-buffer">Scratch Buffer</a></li>
<li class="toctree-l4"><a class="reference internal" href="#in-place-serialization">In-place Serialization</a></li>
<li class="toctree-l4"><a class="reference internal" href="#pvd-integration">PVD Integration</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#completion-tasks">Completion Tasks</a></li>
<li class="toctree-l3"><a class="reference internal" href="#synchronizing-with-other-threads">Synchronizing with Other Threads</a></li>
<li class="toctree-l3"><a class="reference internal" href="#substepping">Substepping</a></li>
<li class="toctree-l3"><a class="reference internal" href="#split-sim">Split sim</a></li>
<li class="toctree-l3"><a class="reference internal" href="#split-fetchresults">Split fetchResults</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="AdvancedCollisionDetection.html">Advanced Collision Detection</a></li>
<li class="toctree-l2"><a class="reference internal" href="Joints.html">Joints</a></li>
<li class="toctree-l2"><a class="reference internal" href="Articulations.html">Articulations</a></li>
<li class="toctree-l2"><a class="reference internal" href="Articulations.html#maximal-coordinate-and-reduced-articulations">Maximal Coordinate and Reduced Articulations</a></li>
<li class="toctree-l2"><a class="reference internal" href="Articulations.html#maximal-coordinate-articulations">Maximal Coordinate Articulations</a></li>
<li class="toctree-l2"><a class="reference internal" href="Articulations.html#reduced-coordinate-articulations">Reduced Coordinate Articulations</a></li>
<li class="toctree-l2"><a class="reference internal" href="OriginShift.html">Scene Origin</a></li>
<li class="toctree-l2"><a class="reference internal" href="GPURigidBodies.html">GPU Rigid Bodies</a></li>
<li class="toctree-l2"><a class="reference internal" href="GeometryQueries.html">Geometry Queries</a></li>
<li class="toctree-l2"><a class="reference internal" href="SceneQueries.html">Scene Queries</a></li>
<li class="toctree-l2"><a class="reference internal" href="Vehicles.html">Vehicles</a></li>
<li class="toctree-l2"><a class="reference internal" href="CharacterControllers.html">Character Controllers</a></li>
<li class="toctree-l2"><a class="reference internal" href="DebugVisualization.html">Debug Visualization</a></li>
<li class="toctree-l2"><a class="reference internal" href="VisualDebugger.html">PhysX Visual Debugger (PVD)</a></li>
<li class="toctree-l2"><a class="reference internal" href="Statistics.html">Simulation Statistics</a></li>
<li class="toctree-l2"><a class="reference internal" href="Serialization.html">Serialization</a></li>
<li class="toctree-l2"><a class="reference internal" href="ExtendingSerialization.html">Extending Serialization</a></li>
<li class="toctree-l2"><a class="reference internal" href="BestPractices.html">Best Practices Guide</a></li>
<li class="toctree-l2"><a class="reference internal" href="MigrationFrom28.html">Migrating From PhysX SDK 2.x to 3.x</a></li>
<li class="toctree-l2"><a class="reference internal" href="MigrationTo33.html">Migrating From PhysX SDK 3.2 to 3.3</a></li>
<li class="toctree-l2"><a class="reference internal" href="MigrationTo34.html">Migrating From PhysX SDK 3.3 to 3.4</a></li>
<li class="toctree-l2"><a class="reference internal" href="MigrationTo40.html">Migrating From PhysX SDK 3.4 to 4.0</a></li>
</ul>
</li>
</ul>

            
          
        </div>
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../Index.html">Python</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="../Index.html">Docs</a> &raquo;</li>
        
          <li><a href="Index.html">User's Guide</a> &raquo;</li>
        
      <li>Simulation</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
            
        
      </li>
    
  </ul>

  
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
  <div class="section" id="simulation">
<span id="id1"></span><h1>Simulation<a class="headerlink" href="#simulation" title="Permalink to this headline">¶</a></h1>
<div class="section" id="callback-sequence">
<span id="callbacks"></span><h2>Callback Sequence<a class="headerlink" href="#callback-sequence" title="Permalink to this headline">¶</a></h2>
<p>The simplest type of simulation callbacks are the events.  Using callbacks the application can simply listen for events and react as required, provided the callbacks obey the rule that SDK state changes are forbidden.  This restriction  may be a bit surprising given that the SDK permits writes to an inactive back-buffer while the simulation is running. Event callbacks, however, are not called from within the simulation thread, but rather from inside fetchResults().  The key point here is that fetchResults() processes the buffered writes, meaning that writing to the SDK from an event callback can be a particularly fragile affair.  To avoid this fragility it is necessary to impose the rule that SDK state changes are not permitted from an event callback.</p>
<p>Inside fetchResults(), among other things, the buffers are swapped.  More specifically, this means that properties of each object's internal simulation state are copied to the API-visible state.  Some event callbacks happen before this swap, and some after.  The events that happen before are:</p>
<blockquote>
<div><ul class="simple">
<li>onTrigger</li>
<li>onContact</li>
<li>onConstraintBreak</li>
</ul>
</div></blockquote>
<p>When these events are received in the callback, the shapes, actors, etc. will still be in the state they were in immediately before the simulation started.  This is preferable, because these events were detected early on during the simulation, before objects were integrated (moved) forward.  For example, a pair of shapes that get an onContact() to report that they are in contact will still be in contact when the call is made, even though they may have bounced apart again after fetchResults() returns.</p>
<p>On the other hand, these events are sent after the swap:</p>
<blockquote>
<div><ul class="simple">
<li>onSleep</li>
<li>onWake</li>
</ul>
</div></blockquote>
<p>Sleep information is updated after objects have been integrated, so it makes sense to send these events after the swap.</p>
<p>To 'listen' to any of these events it is necessary to first subclass PxSimulationEventCallback so that the various virtual functions may be implemented as desired.  An instance of this subclass can then be registered per scene with either PxScene::setSimulationEventCallback or PxSceneDesc::simulationEventCallback.  Following these steps alone will ensure that constraint break events are successfully reported.  One further step is required to report sleep and wake events: to avoid the expense of reporting all sleep and wake events, actors identified as worthy of sleep/wake notification require the flag PxActorFlag::eSEND_SLEEP_NOTIFIES to be raised.  Finally, to receive onContact and onTrigger events it is necessary to set a flag in the filter shader callback for all pairs of interacting objects for which events are required.  More details of the filter shader callback can be found in Section <a class="reference internal" href="RigidBodyCollision.html#collisionfiltering"><em>Collision Filtering</em></a>.</p>
</div>
<div class="section" id="simulation-memory">
<span id="id2"></span><h2>Simulation memory<a class="headerlink" href="#simulation-memory" title="Permalink to this headline">¶</a></h2>
<p>PhysX relies on the application for all memory allocation. The primary interface is via the PxAllocatorCallback interface required to initialize the SDK:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">class</span> <span class="nc">PxAllocatorCallback</span>
<span class="p">{</span>
<span class="nl">public:</span>
    <span class="k">virtual</span> <span class="o">~</span><span class="n">PxAllocatorCallback</span><span class="p">()</span> <span class="p">{}</span>
    <span class="k">virtual</span> <span class="kt">void</span><span class="o">*</span> <span class="n">allocate</span><span class="p">(</span><span class="kt">size_t</span> <span class="n">size</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">typeName</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">filename</span><span class="p">,</span>
        <span class="kt">int</span> <span class="n">line</span><span class="p">)</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">virtual</span> <span class="kt">void</span> <span class="n">deallocate</span><span class="p">(</span><span class="kt">void</span><span class="o">*</span> <span class="n">ptr</span><span class="p">)</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<p>After the self-explanatory function argument describing the size of the allocation, the next three function arguments are an identifier name, which identifies the type of allocation, and the __FILE__ and __LINE__ location inside the SDK code where the allocation was made.  More details of these function arguments can be found in the PhysXAPI documentation.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">An important change since 2.x:  The SDK now requires that the memory that is returned be 16-byte aligned.  On many platforms malloc() returns memory that is 16-byte aligned, but on Windows the system function _aligned_malloc() provides this capability.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">On some platforms PhysX uses system library calls to determine the correct type name, and the system function that returns the type name may call the system memory allocator. If you are instrumenting system memory allocations, you may observe this behavior. To prevent PhysX requesting type names, disable allocation names using the method PxFoundation::setReportAllocationNames().</p>
</div>
<p>Minimizing dynamic allocation is an important aspect of performance tuning.  PhysX provides several mechanisms to control and analyze memory usage.  These shall be discussed in turn.</p>
<div class="section" id="scene-limits">
<h3>Scene Limits<a class="headerlink" href="#scene-limits" title="Permalink to this headline">¶</a></h3>
<p>The number of allocations for tracking objects can be minimized by presizing the capacities of scene data structures, using either PxSceneDesc::limits before creating the scene or the function PxScene::setLimits(). It is useful to note that these limits do not represent hard limits, meaning that PhysX will automatically perform further allocations if the number of objects exceeds the scene limits.</p>
</div>
<div class="section" id="k-data-blocks">
<h3>16K Data Blocks<a class="headerlink" href="#k-data-blocks" title="Permalink to this headline">¶</a></h3>
<p>Much of the memory PhysX uses for simulation is held in a pool of blocks, each 16K in size.  The initial number of blocks allocated to the pool can be controlled by setting PxSceneDesc::nbContactDataBlocks, while the maximum number of blocks that can ever be in the pool is governed by PxSceneDesc::maxNbContactDataBlocks. If PhysX internally needs more blocks than nbContactDataBlocks then it will automatically allocate further blocks to the pool until the number of blocks reaches maxNbContactDataBlocks.  If PhysX subsequently needs more blocks than the maximum number of blocks then it will simply start dropping contacts and joint constraints.  When this happens warnings are passed to the error stream in the PX_CHECKED configuration.</p>
<p>To help tune nbContactDataBlocks and maxNbContactDataBlocks it can be useful to query the number of blocks currently allocated to the pool using the function PxScene::getNbContactDataBlocksUsed().  It can also be useful to query the maximum number of blocks that can ever be allocated to the pool with PxScene::getMaxNbContactDataBlocksUsed.</p>
<p>Unused blocks can be reclaimed using PxScene::flushSimulation().  When this function is called any allocated blocks not required by the current scene state will be deleted so that they may be reused by the application.  Additionally, a number of other memory resources are freed by shrinking them to the minimum size required by the scene configuration.</p>
</div>
<div class="section" id="scratch-buffer">
<h3>Scratch Buffer<a class="headerlink" href="#scratch-buffer" title="Permalink to this headline">¶</a></h3>
<p>A scratch memory block may be passed as a function argument to the function PxScene::simulate.  As far as possible, PhysX will internally allocate temporary buffers from the scratch memory block, thereby reducing the need to perform temporary allocations from PxAllocatorCallback.   The block may be reused by the application after the PxScene::fetchResults() call, which marks the end of simulation.  One restriction on the scratch memory block is that it must be a multiple of 16K, and it must be 16-byte aligned.</p>
</div>
<div class="section" id="in-place-serialization">
<h3>In-place Serialization<a class="headerlink" href="#in-place-serialization" title="Permalink to this headline">¶</a></h3>
<p>PhysX objects cab be stored in memory owned by the application using PhysX' binary deserialization mechanism. See <a class="reference internal" href="Serialization.html#serialization"><em>Serialization</em></a> for details.</p>
</div>
<div class="section" id="pvd-integration">
<h3>PVD Integration<a class="headerlink" href="#pvd-integration" title="Permalink to this headline">¶</a></h3>
<p>Detailed information about memory allocation can be recorded and displayed in the PhysX Visual Debugger. This memory profiling feature can be configured by setting the trackOutstandingAllocations flag when calling PxCreatePhysics(), and raising the flag PxVisualDebuggerConnectionFlag::eMEMORY when connecting to the debugger with PxVisualDebuggerExt::createConnection().</p>
</div>
</div>
<div class="section" id="completion-tasks">
<h2>Completion Tasks<a class="headerlink" href="#completion-tasks" title="Permalink to this headline">¶</a></h2>
<p>A completion task is a task that executes immediately after PxScene::simulate has exited.  If PhysX has been configured to use worker threads then PxScene::simulate will start simulation tasks on the worker threads and will likely exit before the worker threads have completed the work necessary to complete the scene update.  As a consequence, a typical completion task would first need to call PxScene::fetchResults(true) to ensure that fetchResults blocks until all worker threads started during simulate() have completed their work.  After calling fetchResults(true), the completion task can perform any other post-physics work deemed necessary by the application:</p>
<blockquote>
<div>scene.fetchResults(true);
game.updateA();
game.updateB();
...
game.updateZ();</div></blockquote>
<p>The completion task is specified as a function argument in PxScene::simulate.  More details can be found in the PhysAPI documentation.</p>
</div>
<div class="section" id="synchronizing-with-other-threads">
<h2>Synchronizing with Other Threads<a class="headerlink" href="#synchronizing-with-other-threads" title="Permalink to this headline">¶</a></h2>
<p>An important consideration for substepping is that simulate() and fetchResults() are classed as write calls on the scene, and it is therefore illegal to read from or write to a scene while those functions are running.  For the simulate() function it is important to make the distinction between running and ongoing.  In this context, it is illegal to read or write to a scene before simulate() exits.  It is perfectly legal, however, to read or write to a scene after simulate() has exited but before the worker threads that started during the simulate() call have completed their work.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">PhysX does not lock its scene graph, but it will report an error in checked build if it detects that multiple threads make concurrent calls to the same scene, unless they are all read calls.</p>
</div>
</div>
<div class="section" id="substepping">
<h2>Substepping<a class="headerlink" href="#substepping" title="Permalink to this headline">¶</a></h2>
<p>For reasons of fidelity simulation or better stability it is often desired that the simulation frequency of PhysX be higher than the update rate of the application.  The simplest way to do this is just to call simulate() and fetchResults() multiple times:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">for</span><span class="p">(</span><span class="n">PxU32</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">substepCount</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
    <span class="p">...</span> <span class="n">pre</span><span class="o">-</span><span class="n">simulation</span> <span class="n">work</span> <span class="p">(</span><span class="n">update</span> <span class="n">controllers</span><span class="p">,</span> <span class="n">etc</span><span class="p">)</span> <span class="p">...</span>
    <span class="n">scene</span><span class="o">-&gt;</span><span class="n">simulate</span><span class="p">(</span><span class="n">substepSize</span><span class="p">);</span>
    <span class="n">scene</span><span class="o">-&gt;</span><span class="n">fetchResults</span><span class="p">(</span><span class="nb">true</span><span class="p">);</span>
    <span class="p">...</span> <span class="n">post</span> <span class="n">simulation</span> <span class="n">work</span> <span class="p">(</span><span class="n">process</span> <span class="n">physics</span> <span class="n">events</span><span class="p">,</span> <span class="n">etc</span><span class="p">)</span> <span class="p">...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Sub-stepping can also be integrated with the completion task feature of the simulate() function.  To illustrate this, consider the situation where the scene is simulated until the graphics component signals that it has completed updating the render state of the scene.  Here, the completion task will naturally run after simulate() has exited.  Its first job will be to block with fetchResults(true) to ensure that it waits until both simulate() and fetchResults() have completed their sequential work.  When the completion task is able to proceed its next work item will be to query the graphics component to check if another simulate() is required or if it can exit.  In the case that another simulate() step is required it will clearly need to pass a completion task to simulate().  A tricky point here is that a completion task cannot submit itself as the next completion task because it would cause an illegal recursion.  A solution to this problem might to be to have two completion tasks where each stores a reference to the other.  Each completion task can then pass its partner to simulate():</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">scene</span><span class="p">.</span><span class="n">fetchResults</span><span class="p">(</span><span class="nb">true</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">graphics</span><span class="p">.</span><span class="n">isComplete</span><span class="p">())</span>
<span class="p">{</span>
    <span class="n">scene</span><span class="p">.</span><span class="n">simulate</span><span class="p">(</span><span class="n">otherCompletionTask</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="split-sim">
<h2>Split sim<a class="headerlink" href="#split-sim" title="Permalink to this headline">¶</a></h2>
<p>As an alternative to simulate(), you can split the simulation into two different phases, collide() and advance(). For some properties, called write-through properties, modifications during the collide() phase will be seen immediately by the subsequent advance() phase. This allows collide() to begin before the data required by advance() is available and to run in parallel with application side logic that generates inputs to advance(). This is particularly useful for animation logic generating kinematic targets, and for controllers applying forces to bodies. The write-through properties are listed below:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">addForce</span><span class="p">()</span><span class="o">/</span><span class="n">addTorque</span><span class="p">()</span><span class="o">/</span><span class="n">clearForce</span><span class="p">()</span><span class="o">/</span><span class="n">clearTorque</span><span class="p">()</span>
<span class="n">setAngularVelocity</span><span class="p">()</span><span class="o">/</span><span class="n">setLinearVelocity</span><span class="p">()</span>
<span class="n">setKinematicTarget</span><span class="p">()</span>
<span class="n">wakeUp</span><span class="p">()</span>
<span class="n">setWakeCounter</span><span class="p">()</span>
</pre></div>
</div>
<p>When using the split sim, a physics simulation loop would look like this:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">scene</span><span class="p">.</span><span class="n">collide</span><span class="p">(</span><span class="n">dt</span><span class="p">)</span>
<span class="n">scene</span><span class="p">.</span><span class="n">fetchCollision</span><span class="p">()</span>
<span class="n">scene</span><span class="p">.</span><span class="n">advance</span><span class="p">()</span>
<span class="n">scene</span><span class="p">.</span><span class="n">fetchResults</span><span class="p">()</span>
</pre></div>
</div>
<p>Any other sequence of API calls is illegal. The SDK will issue error messages. The users can interleave the physics-dependent application logic between collide() and fetchCollision:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">scene</span><span class="p">.</span><span class="n">collide</span><span class="p">(</span><span class="n">dt</span><span class="p">)</span>
<span class="n">physics</span><span class="o">-</span><span class="n">dependent</span> <span class="n">game</span> <span class="n">logic</span><span class="p">(</span><span class="n">anmimation</span><span class="p">,</span> <span class="n">rendering</span><span class="p">)</span>
<span class="n">scene</span><span class="p">.</span><span class="n">fetchCollision</span><span class="p">()</span>
</pre></div>
</div>
<p>fetchCollision() will wait until collide() has finished before it updates the write-through properties in the SDK. Once fetchCollision() has completed, any state modification performed on the objects in the executing scene will be buffered and will not be reflected until the simulation and a call to fetchResults() has completed. The solver will take the write-through properties into account when computing the new sets of velocities and poses for the actors being simulated.</p>
</div>
<div class="section" id="split-fetchresults">
<h2>Split fetchResults<a class="headerlink" href="#split-fetchresults" title="Permalink to this headline">¶</a></h2>
<p>The fetchResults() method is available in both a standard and split format. The split format offers some advantages over the standard fetchResult() method because it permits the user to parallelize processing of contact reports, which can be expensive when simulating complex scenes.</p>
<p>A simplistic way to use split fetchResults would look something like this:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">gSharedIndex</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

<span class="n">gScene</span><span class="o">-&gt;</span><span class="n">simulate</span><span class="p">(</span><span class="mf">1.0f</span> <span class="o">/</span> <span class="mf">60.0f</span><span class="p">);</span>

<span class="c1">//Call fetchResultsStart. Get the set of pair headers</span>
<span class="k">const</span> <span class="n">PxContactPairHeader</span><span class="o">*</span> <span class="n">pairHeader</span><span class="p">;</span>
<span class="n">PxU32</span> <span class="n">nbContactPairs</span><span class="p">;</span>
<span class="n">gScene</span><span class="o">-&gt;</span><span class="n">fetchResultsStart</span><span class="p">(</span><span class="n">pairHeader</span><span class="p">,</span> <span class="n">nbContactPairs</span><span class="p">,</span> <span class="nb">true</span><span class="p">);</span>

<span class="c1">//Set up continuation task to be run after callbacks have been processed in parallel</span>
<span class="n">callbackFinishTask</span><span class="p">.</span><span class="n">setContinuation</span><span class="p">(</span><span class="o">*</span><span class="n">gScene</span><span class="o">-&gt;</span><span class="n">getTaskManager</span><span class="p">(),</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="n">callbackFinishTask</span><span class="p">.</span><span class="n">reset</span><span class="p">();</span>

<span class="c1">//process the callbacks</span>
<span class="n">gScene</span><span class="o">-&gt;</span><span class="n">processCallbacks</span><span class="p">(</span><span class="o">&amp;</span><span class="n">callbackFinishTask</span><span class="p">);</span>

<span class="n">callbackFinishTask</span><span class="p">.</span><span class="n">removeReference</span><span class="p">();</span>

<span class="n">callbackFinishTask</span><span class="p">.</span><span class="n">wait</span><span class="p">();</span>

<span class="n">gScene</span><span class="o">-&gt;</span><span class="n">fetchResultsFinish</span><span class="p">();</span>
</pre></div>
</div>
<p>The user is free to use their own task/threading system to process the callbacks. However, the PhysX scene provides a utility function that processes the callbacks using multiple threads, which is used in this code snippet. This method takes a continuation task that will be run when the tasks processing callbacks have completed. In this example, the completion task raises an event that can be waited upon to notify the main thread that callback processing has completed.</p>
<p>This feature is demonstrated in SnippetSplitFetchResults. In order to make use of this approach, contact notification callbacks must be thread-safe. Furthermore, for this approach to be beneficial, contact notification callbacks need to be doing a significant amount of work to benefit from multi-threading them</p>
</div>
</div>


           </div>
           
          </div>
          <footer>
  
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="AdvancedCollisionDetection.html" class="btn btn-neutral float-right" title="Advanced Collision Detection" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
      
      
        <a href="RigidBodyDynamics.html" class="btn btn-neutral" title="Rigid Body Dynamics" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
      
    </div>
  

  <hr/>

  <div role="contentinfo">
    <p>
        &copy; Copyright 2008-2021 NVIDIA Corporation, 2788 San Tomas Expressway, Santa Clara, CA 95051 U.S.A. All rights reserved

    </p>
  </div> 

</footer>

        </div>
      </div>

    </section>

  </div>
  


  

    
    
      <script type="text/javascript">
          var DOCUMENTATION_OPTIONS = {
              URL_ROOT:'../',
              VERSION:'4.1',
              LANGUAGE:'',
              COLLAPSE_INDEX:false,
              FILE_SUFFIX:'.html',
              HAS_SOURCE:  true,
              SOURCELINK_SUFFIX: ''
          };
      </script>
        <script type="text/javascript" src="../_static/jquery.js"></script>
        <script type="text/javascript" src="../_static/underscore.js"></script>
        <script type="text/javascript" src="../_static/doctools.js"></script>
    

  

  <script type="text/javascript" src="../_static/js/theme.js"></script>

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(false);
      });
  </script> 

</body>
</html>